﻿// Decompiled with JetBrains decompiler
// Type: Netick.Unity.Angle
// Assembly: Netick.Unity, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E128C7FD-39ED-4452-86AC-6EC748457030
// Assembly location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.Unity.dll
// XML documentation location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.Unity.xml

using System;
using UnityEngine;

#nullable disable
namespace Netick.Unity;

/// <summary>
/// A helper struct that represents an angle in degrees, which automatically wraps to [0, 360) range.
/// </summary>
[SerializeField]
[Serializable]
/// <summary>
/// Construct from raw degrees (auto-wrapped to [0, 360) internally).
/// </summary>
public struct Angle(float degrees) : IEquatable<Angle>
{
  [SerializeField]
  internal int _rawValue = 0;

  public unsafe float Value
  {
    get
    {
      fixed (Angle* data = &this)
        return NetickUnityUtils.GetFloat((int*) data, 1f / 1000f);
    }
    set
    {
      fixed (Angle* data = &this)
        NetickUnityUtils.SetFloat((int*) data, value, 1000f);
    }
  }

  public static float Wrap(float angle)
  {
    angle %= 360f;
    if ((double) angle < 0.0)
      angle += 360f;
    return angle;
  }

  public static unsafe Angle CreateAngle(int* data)
  {
    return new Angle() { _rawValue = *data };
  }

  public static Angle operator +(Angle a, Angle b) => new Angle(a.Value + b.Value);

  public static Angle operator -(Angle a, Angle b) => new Angle(a.Value - b.Value);

  public static Angle operator *(Angle a, float scalar) => new Angle(a.Value * scalar);

  public static Angle operator /(Angle a, float scalar) => new Angle(a.Value / scalar);

  public static implicit operator Angle(float degrees) => new Angle(degrees);

  public static implicit operator float(Angle a) => Angle.Wrap(a.Value);

  public bool Equals(Angle other) => (double) this.Value == (double) other.Value;

  public override bool Equals(object obj)
  {
    return obj is Angle angle && (double) angle.Value == (double) this.Value;
  }

  public override int GetHashCode() => this.Value.GetHashCode();

  public override string ToString() => $"{this.Value}°";
}
